package com.zmx.user.service;

import com.zmx.common.common.service.BaseService;
import com.zmx.common.common.utils.Lock.RedissonLock;
import com.zmx.common.common.utils.bitmap.SimpleBitMap;
import com.zmx.user.dto.MemberBlacklistDto;
import com.zmx.user.entity.MemberBlacklist;
import com.zmx.user.repository.MemberBlacklistRepository;
import com.zmx.user.service.mapper.MemberBlacklistMapper;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @author zhaomxr
 */
@Slf4j
@Service
public class MemberBlacklistService extends BaseService<MemberBlacklist, MemberBlacklistDto, MemberBlacklistRepository, MemberBlacklistMapper> {

    private String BLACKLISTCACHE_KEY = "blacklist";
    private String BLACKLISTCACHE_UPDATE_KEY = "blacklist_update";

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private RedissonLock redissonLock;

    /**
     * 根据用户id和ip查询黑名单
     * @param memberId
     * @param ip
     * @return
     */
    public MemberBlacklist getBlacklist(Long memberId, String ip) {
        List<MemberBlacklist> memberBlacklists = new ArrayList<MemberBlacklist>();
        if (memberId != null && memberId > 0 && !StringUtils.isEmpty(ip)) {
            memberBlacklists = repository.findByMemberIdOrIp(memberId, ip);
        } else if (memberId != null && memberId > 0 && StringUtils.isEmpty(ip)) {
            memberBlacklists = repository.findByMemberId(memberId);
        } else if ((memberId == null || memberId <= 0) && !StringUtils.isEmpty(ip)) {
            memberBlacklists = repository.findByIp(ip);
        }

        if (memberBlacklists != null && memberBlacklists.size() > 0) {
            return memberBlacklists.get(0);
        }
        return null;
    }

    /**
     * 新增用户黑名单
     */
    @Transactional(rollbackFor = Exception.class)
    public void addBlacklist(MemberBlacklistDto memberBlacklistDto) {
        //这里可能由于并发引起缓存数据不一致，有些黑名单可能无法及时更新缓存，不影响，最多再次查询数据库后重新更新缓存
        RLock rLock = null;
        try {
            MemberBlacklistDto saveBlacklistDto = this.create(memberBlacklistDto);

            if (saveBlacklistDto != null) {
                SimpleBitMap simpleBitMap = new SimpleBitMap(1);
                rLock = redissonLock.lock("simpleBitMap");
                boolean tryLock = rLock.tryLock();
                if (tryLock) {
                    Object object = redisTemplate.opsForValue().get(BLACKLISTCACHE_KEY);
                    if (object != null) {
                        simpleBitMap = (SimpleBitMap) object;
                    }
                    simpleBitMap.add(memberBlacklistDto.getMemberId().intValue());
                    redisTemplate.opsForValue().set(BLACKLISTCACHE_KEY, simpleBitMap);
                    redisTemplate.opsForValue().set(BLACKLISTCACHE_UPDATE_KEY, true);
                }
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        } finally {
            if (rLock != null) {
                redissonLock.unLock(rLock);
            }
        }
    }
}
